package com.whty.system.util;

import java.util.Random;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public  class Fn {
	public static String Hex(String res, int i, int j) {
		String resp=convertHexToString(res);
	return resp.substring(i, i+j);
          }
	
	public static  String convertStringToHex(String str){

		  char[] chars = str.toCharArray();

		  StringBuffer hex = new StringBuffer();
		  for(int i = 0; i < chars.length; i++){
		    hex.append(Integer.toHexString((int)chars[i]));
		  }

		  return hex.toString();
		  }

		  public static String convertHexToString(String hex){

		  StringBuilder sb = new StringBuilder();
		  StringBuilder temp = new StringBuilder();

		  //49204c6f7665204a617661 split into two characters 49, 20, 4c...
		  for( int i=0; i<hex.length()-1; i+=2 ){

		      //grab the hex in pairs
		      String output = hex.substring(i, (i + 2));
		      //convert hex to decimal
		      int decimal = Integer.parseInt(output, 16);
		      //convert the decimal to character
		      sb.append((char)decimal);

		      temp.append(decimal);
		  }

		  return sb.toString();
		  }

		  public static String strrev(String sCrc32) {
		
//		return new StringBuilder(sCrc32).reverse().toString();
		
		String s="";
		for(int i=sCrc32.length()/2;i>0;i--)
		{
			
			s+=sCrc32.substring(i*2-2, i*2);
		}
		return s;
	}
	public static String Crc32(String data, String init) {
		String s=  GPMethods.generateCRC32(CommonMethods.stringToBytes(data),CommonMethods.stringToBytes(init),1);
		return s;
	}
	public static String  calcSessionKey(String sinputData,String skey)
	{
		String scmac="";
		String sMdata=sinputData;
		String sconst_Rb="00000000000000000000000000000087";
		String sCHIPK=AESCoder.cbcEnc("00000000000000000000000000000000", skey,"00000000000000000000000000000000");
		String sHbyte=left(sCHIPK,1);
		String iHbit=bit(atoi(sHbyte),7);
		String skey1="";
		if(iHbit.equals("0"))
		{
			 skey1=shift(sCHIPK,1,1);
		}else {
			 skey1 = xor(shift(sCHIPK,1,1),sconst_Rb);
		}
		sHbyte = left(skey1,1);
		iHbit = bit(atoi(sHbyte),7);
		String skey2="";
		if(iHbit.equals("0"))
		{
			skey2 = shift(skey1,1,1);
		}else {
			skey2 = xor(shift(skey1,1,1),sconst_Rb);
		}
		int ilen = strlen(sMdata);
		int iblocklen = strlen(skey);
		int imod = mod(ilen,iblocklen);
		int itime = ilen/iblocklen;

		if(imod == 0 && itime != 0)
		{
			String slast = xor(right(sMdata,strlen(skey)),skey1);
			String smacdata = left(sMdata,ilen-strlen(skey)) + slast;
			 scmac = right(AESCoder.cbcEnc(smacdata,skey,"00000000000000000000000000000000"),16);
		}else {
			 sMdata = sMdata+80;
					ilen = strlen(sMdata);
					int  imod1 = mod(ilen,strlen(skey));
					while(imod1!=0)
					{
						sMdata = sMdata+00;
						ilen = strlen(sMdata);
						imod1 = mod(ilen,strlen(skey));
					}
					
					String slast = xor(right(sMdata,strlen(skey)),skey2);
					String smacdata = left(sMdata,ilen-strlen(skey)) + slast;
					 scmac = right(AESCoder.cbcEnc(smacdata,skey,"00000000000000000000000000000000"),16);
		}

				
	    return  scmac;
	}
	
	public static int mod(int ilen, int iblocklen) {
		return ilen%iblocklen;
	}
	public static  int strlen(String str)
	{
		return str.length()/2;
	}
	public static String shift(String sCHIPK, int m, int j) {
		  String s="";
		  for (int i = 0; i < sCHIPK.length(); i++) {
				s+=g(sCHIPK.charAt(i));
			}
	        s=s.substring(m)+StringUtil.padding("", m, 1,1);
	        String r="";
	        int len=s.length()/4;
	        for(int i=0;i<len;i++)
	        {
	        	String num=s.substring(i*4, i*4+4);
	        	r+=k(num);
	        }
	       return r;
	}
	public static String bit(int a,int b)
	{
		b=b+1;
		String s=Integer.toBinaryString(a);
		if(s.length()<b)
		{
			return "0";
		}else {
			return s.substring(s.length()-b, s.length()-b+1);
		}
		
	}
	public static int atoi(String s)
	{
		int valueTen2 = Integer.parseInt(s,16);
		return valueTen2;
	}
	public static String xor(String b1, String b2) {
		  if (b1.length() != b2.length())
		    {
		      return null;
		    }
		    byte[] byte1 = Converts.stringToBytes(b1);
		    byte[] byte2 = Converts.stringToBytes(b2);

		    byte[] result = new byte[byte1.length];
		    for (int i = 0; i < byte1.length; i++)
		    {
		      int temp = (byte1[i] ^ byte2[i]) & 0xff;
		      result[i] = (byte) temp;
		    }
		    return Converts.bytesToHex(result).toUpperCase();
	}
	
	public static String xor2(String b1, String b2) {
		String loc="";
		 for(int i=0;i<b1.length()/2-1;i++)
		 {
			 if(i==0)
			 {
				 loc=b1.substring(i, i+2);
				 loc=xor(loc,b1.substring(i*2+2, i*2+4));
			 }else
			 {
				 loc=xor(loc,b1.substring(i*2+2, i*2+4));
			 }
		 }
		   return loc;
	}
	
	public static String xor3(String b1, String b2) {
		int length=0;
		int a=b1.length()%b2.length();
		if(a==0)
		{
			length=b1.length()/b2.length();
		}else
		{
			length=b1.length()/b2.length()+1;
		}
		length=length*b2.length();
		b1=StringUtil.padding(b1, length, 1,2);
		String loc="";
		 for(int i=0;i<b1.length()/4-1;i++)
		 {
			 if(i==0)
			 {
				 loc=b1.substring(i, i+4);
				 loc=xor(loc,b1.substring(i*4+4, i*4+8));
			 }else
			 {
				 loc=xor(loc,b1.substring(i*4+4, i*4+8));
			 }
		 }
		   return loc;
	}
	public static String  right(String s,int len)
	{
		return s.substring(s.length()-len*2);
	}
	public static String left(String s,int len)
	{
		return s.substring(0, len*2);
	}
	
	
	public  static String randomHexString(int len)  {
		try {
			StringBuffer result = new StringBuffer();
			for(int i=0;i<len;i++) {
				result.append(Integer.toHexString(new Random().nextInt(16)));
			}
			return result.toString().toUpperCase();
			
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			
		}
		return null;
		
	}
	 
	 private static String g(char charAt) {
			// TODO Auto-generated method stub
			switch (charAt) {
			case '0':	
				return "0000";
			case '1':	
				return "0001";
			case '2':	
				return "0010";
			case '3':	
				return "0011";
			case '4':	
				return "0100";
			case '5':	
				return "0101";
			case '6':	
				return "0110";
			case '7':	
				return "0111";
			case '8':	
				return "1000";
			case '9':	
				return "1001";
			case 'A':	
				return "1010";
			case 'a':	
				return "1010";
			case 'B':	
				return "1011";
			case 'b':	
				return "1011";
			case 'C':	
				return "1100";
			case 'c':	
				return "1100";
			case 'D':	
				return "1101";
			case 'd':	
				return "1101";
			case 'E':	
				return "1110";
			case 'e':	
				return "1110";
			case 'F':	
				return "1111";
			case 'f':	
				return "1111";
		
			}
			return null;
		}
	 
	 private static String k(String charAt) {
			// TODO Auto-generated method stub
			switch (charAt) {
			case "0000":	
				return "0";
			case "0001":	
				return "1";
			case "0010":	
				return "2";
			case "0011":	
				return "3";
			case "0100":	
				return "4";
			case "0101":	
				return "5";
			case "0110":	
				return "6";
			case "0111":	
				return "7";
			case "1000":	
				return "8";
			case "1001":	
				return "9";
			case "1010":	
				return "A";
			case "1011":	
				return "B";
			case "1100":	
				return "C";
			case "1101":	
				return "D";
			case "1110":	
				return "E";
			case "1111":	
				return "F";
			}
			return null;
		}
	
		public static  String strmid(String str,int pos,int len)
		{
			str=str.replace(" ", "");
			if(len>str.length()-pos)
			{
				return str.substring(pos);
			}else
			{
				return str.substring(pos,pos+len);
			}
		}
		
		public static String asc(String s)
		{
		    String ss = s;
		    byte[] bt = new byte[0];

		    try {
		        bt = ss.getBytes("GBK");
		    }catch (Exception e){
		        e.printStackTrace();
		    }
		    String s1 = "";
		    for (int i = 0; i < bt.length; i++)
		    {
		        String tempStr = Integer.toHexString(bt[i]);
		        if (tempStr.length() > 2)
		            tempStr = tempStr.substring(tempStr.length() - 2);
		        s1 = s1 + tempStr + "";
		    }
		    return s1.toUpperCase();
		}
		
		 /**
		   * ECB模式中的DES/3DES/TDES算法(数据不需要填充),支持8、16、24字节的密钥 说明：3DES/TDES解密算法 等同与
		   * 先用前8个字节密钥DES解密 再用中间8个字节密钥DES加密 最后用后8个字节密钥DES解密 一般前8个字节密钥和后8个字节密钥相同
		   * 
		   * @param key
		   *          加解密密钥(8字节:DES算法 16字节:3DES/TDES算法
		   *          24个字节:3DES/TDES算法,一般前8个字节密钥和后8个字节密钥相同)
		   * @param data
		   *          待加/解密数据(长度必须是8的倍数)
		   * @param mode
		   *          0-加密，1-解密
		   * @return 加解密后的数据 为null表示操作失败
		   */
		  public static String desecb(String key, String data, int mode)
		  {
		    try
		    {

		      // 判断加密还是解密
		      int opmode = (mode == 0) ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE;

		      SecretKey keySpec = null;

		      Cipher enc = null;

		      // 判断密钥长度
		      if (key.length() == 16)
		      {
		        // 生成安全密钥
		        keySpec = new SecretKeySpec(Converts.stringToBytes(key), "DES");
		        // key

		        // 生成算法
		        enc = Cipher.getInstance("DES/ECB/NoPadding");
		      } else if (key.length() == 32)
		      {
		        // 计算加解密密钥，即将16个字节的密钥转换成24个字节的密钥，24个字节的密钥的前8个密钥和后8个密钥相同,并生成安全密钥
		        keySpec = new SecretKeySpec(Converts.stringToBytes(key + key.substring(0, 16)), "DESede");
		        // 将key前8个字节复制到keyecb的最后8个字节

		        // 生成算法
		        enc = Cipher.getInstance("DESede/ECB/NoPadding");
		      } else if (key.length() == 48)
		      {
		        // 生成安全密钥
		        keySpec = new SecretKeySpec(Converts.stringToBytes(key), "DESede"); // key

		        // 生成算法
		        enc = Cipher.getInstance("DESede/ECB/NoPadding");
		      } else
		      {
		    	  System.out.println("key length error");
		        return null;
		      }

		      // 初始化
		      enc.init(opmode, keySpec);

		      // 返回加解密结果
		      return (Converts.bytesToHex(enc.doFinal(Converts.stringToBytes(data)))).toUpperCase(); // 开始计算
		    } catch (Exception e)
		    {
		      e.printStackTrace();
		    }
		    return null;
		  }
}
